﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Reflection;
using System.Text;

namespace System {
    public static partial class Extention {
        /// <summary>
        /// 获取某一列的所有值
        /// </summary>
        /// <typeparam name="T">列数据类型</typeparam>
        /// <param name="dtSource">数据表</param>
        /// <param name="filedName">列名</param>
        /// <returns></returns>
        public static List<T> GetColumnValues<T>(this DataTable dtSource,string filedName) {
            return (from r in dtSource.AsEnumerable() select r.Field<T>(filedName)).ToList<T>();
        }
        public static List<T> ToObject<T>(this DataTable dt) where T : new() {
            List<T> list = new List<T>();
            foreach(DataRow R in dt.Rows)
                list.Add(ToObject<T>(R));
            return list;
        }
        public static T ToObject<T>(this DataRow row) where T : new() {
            T obj = new T();
            Type type = typeof(T);
            string fname; object tv; object fvalue;
            for(int i = 0;i < row.Table.Columns.Count;i++) {
                fname = row.Table.Columns[i].ColumnName;
                fvalue = row[fname];
                PropertyInfo p = type.GetProperty(fname,BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.IgnoreCase);
                if(p != null) {
                    if(p.PropertyType.IsArray)//数组类型,单独处理
                    {
                        p.SetValue(obj,fvalue,null);
                    } else {
                        if(String.IsNullOrEmpty(fvalue.ToString()))//空值
                            tv = p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType) : null;//值类型
                        else
                            tv = System.ComponentModel.TypeDescriptor.GetConverter(p.PropertyType).ConvertFromString(fvalue.ToString());//创建对象
                        p.SetValue(obj,tv,null);
                    }
                }
            }
            return obj;
        }
        public static void ToRow(object obj,DataRow row,bool removeInjection = true) {
            Type type = obj.GetType();
            string fname; object fvalue;
            for(int i = 0;i < row.Table.Columns.Count;i++) {
                fname = row.Table.Columns[i].ColumnName;
                PropertyInfo p = type.GetProperty(fname,
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.IgnoreCase);
                if(p != null) {
                    fvalue = p.GetValue(obj);
                    //移除注入攻击关键词
                    if(p.PropertyType == typeof(string) && fvalue != null && !String.IsNullOrWhiteSpace(fvalue.ToString()))
                        fvalue = fvalue.ToString();
                    row[fname] = fvalue;
                }
            }
        }
        /// <summary>
        ///将DataTable转换为标准的CSV字符串
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns>返回标准的CSV</returns>
        public static string ToCsvStr(this DataTable dt) {
            //以半角逗号（即,）作分隔符，列为空也要表达其存在。
            //列内容如存在半角逗号（即,）则用半角引号（即""）将该字段值包含起来。
            //列内容如存在半角引号（即"）则应替换成半角双引号（""）转义，并用半角引号（即""）将该字段值包含起来。
            StringBuilder sb = new StringBuilder();
            DataColumn colum;
            foreach(DataRow row in dt.Rows) {
                for(int i = 0;i < dt.Columns.Count;i++) {
                    colum = dt.Columns[i];
                    if(i != 0) sb.Append(",");
                    if(colum.DataType == typeof(string) && row[colum].ToString().Contains(",")) {
                        sb.Append("\"" + row[colum].ToString().Replace("\"","\"\"") + "\"");
                    } else sb.Append(row[colum].ToString());
                }
                sb.AppendLine();
            }

            return sb.ToString();
        }
        /// <summary>
        /// 把DataTable转换成Html table
        ///   列1  列2  列3  列4  列5
        ///   值1  值2  值3  值4  值5
        /// </summary>
        /// <param name="dt">DataTable</param>
        /// <returns></returns>
        public static string ToHtmlTable(this DataTable dt) {
            StringBuilder sbHtml = new StringBuilder();
            sbHtml.Append("<table  cellpadding=3 cellspacing=1  border=1 style=\"border-collapse: collapse\">");
            sbHtml.Append("<tr  style=\"text-align: center; COLOR: #0076C8; BACKGROUND-COLOR: #F4FAFF; font-weight: bold\">");
            string[] str = { "style=\"background-color:#dda29a;\"","style=\"background-color:#d98722;\"","style=\"background-color:#cfbd2d;\"","style=\"background-color:#cbd12c;\"","style=\"background-color:#91ca15;\"","style=\"background-color:#6dc71e;\"","style=\"background-color:#25b25c;\"","style=\"background-color:#13a7a2;\"" };
            string aligns = "align=\"right\"";
            for(int i = 0;i < dt.Columns.Count;i++) {
                sbHtml.Append("<th ");
                //sbHtml.Append(str[i]);
                sbHtml.Append(" >");
                sbHtml.Append(dt.Columns[i].ColumnName);
                sbHtml.Append("</th>");
            }
            sbHtml.Append("</tr>");
            for(int i = 0;i < dt.Rows.Count;i++)//行
            {
                sbHtml.Append("<tr>");
                for(int j = 0;j < dt.Columns.Count;j++) {
                    sbHtml.Append("<td ");
                    sbHtml.Append(aligns);
                    sbHtml.Append(" >");
                    sbHtml.Append(dt.Rows[i][j]);
                    sbHtml.Append("</td>");
                }
                sbHtml.Append("</tr>");
            }
            sbHtml.Append("</table>");
            return sbHtml.ToString();
        }
        /// <summary>
        /// 把DataRow转换成Html table
        ///   列1  值1 
        ///   列3  值2  
        /// </summary>
        /// <param name="dt">DataRow</param>
        /// <returns></returns>
        public static string ToHtmlTable2(this DataRow dt) {
            StringBuilder sbHtml = new StringBuilder();
            sbHtml.Append("<table cellpadding=3 cellspacing=1 class=\"table\">");
            for(int i = 0;i < dt.Table.Columns.Count;i++) {
                string colName = dt.Table.Columns[i].ColumnName;
                string colValue = dt[colName].ToString();

                sbHtml.Append("<tr>");
                sbHtml.Append(" <td class=\"text - l\">" + colName + "</td>");
                sbHtml.Append(" <td class=\"text - r\">" + colValue + "</td>");
                sbHtml.Append("</tr>");
            }
            sbHtml.Append("</table>");
            return sbHtml.ToString();
        }

        public static string ToStrJson(this DataTable dt) {
            StringBuilder jsonBuilder = new StringBuilder();
            if(dt != null && dt.Rows.Count > 0) {
                for(int i = 0;i < dt.Rows.Count;i++) {
                    jsonBuilder.Append("{");
                    for(int j = 0;j < dt.Columns.Count;j++) {
                        jsonBuilder.Append("\"");
                        jsonBuilder.Append(dt.Columns[j].ColumnName);
                        jsonBuilder.Append("\":\"");
                        jsonBuilder.Append(dt.Rows[i][j].ToString().Trim());
                        jsonBuilder.Append("\",");
                    }
                    if(dt.Columns.Count > 0) {
                        jsonBuilder.Remove(jsonBuilder.Length - 1,1);
                    }
                    jsonBuilder.Append("},");
                }
                if(dt.Rows.Count > 0) {
                    jsonBuilder.Remove(jsonBuilder.Length - 1,1);
                }
            }
            return jsonBuilder.ToString();
        }
    }
}
